#ifndef HB_LINK_PROTOCOL_H
#define HB_LINK_PROTOCOL_H

// because len is uint8_t = 255
#define LINK_PROTOCOL_DATA_BUFFER_SIZE  255


typedef struct linkProtocol{
	// check sum
	uint8_t m_checksum;
	// ID of message 
	uint8_t m_msgid;
	// message length
	uint8_t m_len;
	// save message date
	uint8_t m_data[LINK_PROTOCOL_DATA_BUFFER_SIZE];
} linkProtocolType;


typedef enum {
    LinkMessageParseStateUninit 			= 0,
    LinkMessageParseStateIdle,
    LinkMessageParseStateGetStart,
    LinkMessageParseStateGetMessageId,
    LinkMessageParseStateGetLen,
    LinkMessageParseStateGetData
} linkProtocolParseStateType;



typedef enum {
    LinkMessageFramingStateIncomplete 		= 0,
    LinkMessageFramingStateOk		 		= 1,
    LinkMessageFramingStateError 			= 2
} linkMessageFramingStateType;

typedef struct linkProtocolState {
	// Number of received messages
    uint8_t m_msgReceived;
	// Parsing state machine
    linkProtocolParseStateType m_parseState;
	// Index in current packet
    uint8_t m_packetIdx;
    uint16_t m_parseError;
} linkProtocolStateType;

enum linkProtocolMessageStatus{
	linkProtocolMessageStatusOk				= 0,
	linkProtocolMessageStatusErr			= 1
};

enum linkProtocolMessageId{
    linkProtocolHeartBeat           		= 0,
    linkProtocolAck         				= 1,
    // assistLand msg number from 2 to 10
    linkProtocolCancelLand					= 2,
    linkProtocolSetLandPoint				= 3,


	//log msg
	linkProtocolLogRequestList				= 11,
	linkProtocolLogRequestData				= 12,
	linkProtocolLogErase					= 13,
	linkProtocolLogRequestEnd				= 14,
	//send to msdk log msg
	linkProtocolSendLogData					= 15,
	linkProtocolSendLogList					= 16,

	//update firware
	linkProtocolUpdateFirware				= 20,
	linkProtocolUpdateFirwareData	 		= 21,
	linkProtocolUpdateFirwareState			= 22
};

enum assistLandSystemState{
	assistLandStartError					= 0,
	monitorFlightState  					= 1,
	controlFlighLand						= 2
};

enum assistAvoidSystemState{
	assistAvoidStartError					= 0,
	moditorFlightState						= 1,
	controlAovid							= 2
};


enum updataFirwareState{
	updataFirwareStateSuccess 				= 0,
	updataFirwareStateRecvData 				= 1,
	updataFirwareStateFailed				= 2
};

enum ackMsgState{
	ackMsgStateOk 							= 0,
	ackMsgStateFailed 						= 1
};

typedef struct heartBeat{
	//see assistLandSystemState for state
    uint8_t m_assistLandSystemState;
}heartBeatType;

typedef struct ackMsg{
	uint8_t m_ackMsgId;
	//0 is success, 1 is failed
	uint8_t m_status;
}ackMsgType;

typedef struct cancelLand{
	uint8_t m_status;
}cancelLandType;

typedef struct logRequestList{
	uint16_t m_start;
	uint16_t m_end;
}logRequestListType;

typedef struct logRequestData{
	uint32_t m_ofs;
	uint32_t m_count;
	uint16_t m_logId;
}logRequestDataType;

typedef struct sendLogData{
	uint32_t m_ofs;
	uint32_t m_count;
	uint16_t m_logId;
	uint8_t  m_data[91];
}sendLogDataType;


typedef struct sendLogList{
	uint32_t m_size;
	uint16_t m_logId;
	uint16_t m_numPosData;
	uint16_t m_lastPosDataNum;
}sendLogListType;

typedef struct logErase{
	uint8_t m_status;
}logEraseType;


typedef struct logRequestEnd{
	uint8_t m_status;
}logRequestEndType;

typedef struct updateFirware{
	uint32_t m_dataSize;
	//md5 128 bit = 16 byte, 16 * 2 = 32.
	uint8_t m_md5Crc[32];
}updateFirwareType;

typedef struct updateFirwareData{
	uint32_t m_ofs;
	uint32_t m_count;
	uint8_t  m_data[90];
}updateFirwareDataType;

typedef struct updateFirwareState{
	// 0 is success, 1 is receive date, 2 is failed.
	uint8_t m_status;
}updateFirwareStateType;

typedef struct setLandPoint{
	uint32_t m_latitude;
	uint32_t m_longitude;
}setLandPointType;

uint16_t packagelinkProtocolToBuffer(uint8_t *buf, uint8_t msgId,uint8_t *msgData, uint16_t msgLen);
uint8_t handleLinkProtocolData(linkProtocolType *recvMsg, uint8_t c);
#endif  //HB_LINK_PROTOCOL_H